package br.com.assinchronus.negocio;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import br.com.assinchronus.componentes.Casa;
import br.com.assinchronus.componentes.Peao;

public class RegraDama {

	public JogadasEnum verificaJogada(Casa casaAtual, Casa casaFinal, Casa[] tab, boolean sequencia) {
		int posicaoAtual = casaAtual.getPosicao();
		int posicaoFinal = 0;
		int dif = 0;

		if (casaFinal == null) {
			return JogadasEnum.INVALIDA;
		}

		posicaoFinal = casaFinal.getPosicao();
		dif = posicaoFinal - posicaoAtual;
		if (casaFinal.getPeca() != null) {
			return JogadasEnum.INVALIDA;
		}
		
		if (dif == 20) {
			switch (posicaoAtual) {
			case 3:
			case 4:
			case 8:
			case 12:
			case 13:
				return moverDamaNorte(tab, posicaoAtual, posicaoFinal, 4);
			case 1:
			case 2:
			case 5:
			case 6:
			case 10:
			case 11:
			case 14:
			case 15:
				return moverDamaNorte(tab, posicaoAtual, posicaoFinal, 5);
			default:
				break;
			}
		} else if (dif == -20) {
			switch (posicaoAtual) {
			case 23:
			case 24:
			case 28:
			case 32:
			case 33:
				return moverDamaSul(tab, posicaoAtual, posicaoFinal, -4);

			case 21:
			case 22:
			case 25:
			case 26:
			case 30:
			case 31:
			case 34:
			case 35:
				return moverDamaSul(tab, posicaoAtual, posicaoFinal, -5);
			default:
				break;
			}
		}

		if (dif > 0) {
			if (dif % 5 == 0 && dif % 4 == 0 || dif % 4 == 0) {
				return moverDamaNorte(tab, posicaoAtual, posicaoFinal, 4);
			} else if (dif % 5 == 0) {
				return moverDamaNorte(tab, posicaoAtual, posicaoFinal, 5);
			}
		} else {
			if (dif % 5 == 0 && dif % 4 == 0 || dif % 4 == 0) {
				return moverDamaSul(tab, posicaoAtual, posicaoFinal, -4);
			} else if (dif % 5 == 0) {
				return moverDamaSul(tab, posicaoAtual, posicaoFinal, -5);
			}
		}

		return JogadasEnum.INVALIDA;
	}

	// TODO: Refatorar moverDamaNorte e moverDamaSul.
	private JogadasEnum moverDamaNorte(Casa[] tab, int posicaoAtual, int posicaoFinal, int i) {
		int count = 0;

		for (int j = posicaoAtual + i; j <= posicaoFinal; j += i) {
			if (j % 9 == 0) {
				return JogadasEnum.INVALIDA;
			}
			if (tab[j].getPeca() != null) {
				if (!tab[j].getPeca().isCapturada() && tab[j].getPeca().getCor() != tab[posicaoAtual].getPeca().getCor()) {
					count++;
					if (count == 2) {
						return JogadasEnum.INVALIDA;
					}
				} else {
					return JogadasEnum.INVALIDA;
				}
			}
			if (j == posicaoFinal && count == 1) {
				return JogadasEnum.COMER;
			}
		}

		return JogadasEnum.MOVER_DAMA;
	}

	private JogadasEnum moverDamaSul(Casa[] tab, int posicaoAtual, int posicaoFinal, int i) {
		int count = 0;

		for (int j = posicaoAtual + i; j >= posicaoFinal; j += i) {
			if (j % 9 == 0) {
				return JogadasEnum.INVALIDA;
			}
			if (tab[j].getPeca() != null) {
				if (!tab[j].getPeca().isCapturada() && tab[j].getPeca().getCor() != tab[posicaoAtual].getPeca().getCor()) {
					count++;
					if (count == 2) {
						return JogadasEnum.INVALIDA;
					}
				} else {
					return JogadasEnum.INVALIDA;
				}
			}
			if (j == posicaoFinal && count == 1) {
				return JogadasEnum.COMER;
			}
		}

		return JogadasEnum.MOVER_DAMA;
	}

	public List<Casa> verificaSequencia(Casa casaAtual, Casa[] tab) {

		List<Casa> listCasas = new ArrayList<Casa>();
		int posicao = casaAtual.getPosicao();

		for (int i = posicao - 5; i > 0; i -= 5) {
			if (i % 9 == 0) {
				break;
			}
			if (verificaJogada(casaAtual, tab[i], tab, true) == JogadasEnum.COMER) {
				listCasas.add(tab[i]);
			}
		}

		for (int i = posicao - 4; i > 0; i -= 4) {
			if (i % 9 == 0) {
				break;
			}
			if (verificaJogada(casaAtual, tab[i], tab, true) == JogadasEnum.COMER) {
				listCasas.add(tab[i]);
			}
		}

		for (int i = posicao + 5; i < 36; i += 5) {
			if (i % 9 == 0) {
				break;
			}
			if (verificaJogada(casaAtual, tab[i], tab, true) == JogadasEnum.COMER) {
				listCasas.add(tab[i]);
			}
		}

		for (int i = posicao + 4; i < 36; i += 4) {
			if (i % 9 == 0) {
				break;
			}

			if (verificaJogada(casaAtual, tab[i], tab, true) == JogadasEnum.COMER) {
				listCasas.add(tab[i]);
			}
		}

		return listCasas;
	}

	public Map<Casa, List<Casa>> verificaObrigatoria(Casa[] tab, int cor) {
		Map<Casa, List<Casa>> obrigatorias = new HashMap<Casa, List<Casa>>();

		for (int i = 1; i < tab.length; i++) {
			if (i % 9 == 0 || (tab[i].getPeca() == null || tab[i].getPeca() instanceof Peao || tab[i].getPeca().getCor() != cor)) {
				continue;
			}

			List<Casa> sequenciaList = verificaSequencia(tab[i], tab);

			if (sequenciaList != null && sequenciaList.size() > 0) {
				obrigatorias.put(tab[i], sequenciaList);
			}

		}

		return obrigatorias;
	}

}
